package org.fujay.langchain4jserver.domain.application.aggregate;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NonNull;
import org.fujay.langchain4jserver.domain.application.entity.App;
import org.fujay.langchain4jserver.domain.application.entity.AppConfigHistory;
import org.fujay.langchain4jserver.domain.application.vo.AppConfigSnapshot;
import org.fujay.langchain4jserver.domain.application.vo.AppId;
import org.fujay.langchain4jserver.domain.application.vo.Version;
import org.fujay.langchain4jserver.domain.knowledge.vo.KnowledgeBaseId;
import org.fujay.langchain4jserver.domain.model.vo.ModelId;
import org.fujay.langchain4jserver.domain.shared.exception.DomainException;

import java.util.*;

/**
 * 应用聚合根
 */
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class AppAggregate {

    @NonNull
    private final App app;

    // 配置历史记录，按版本降序排列
    private final List<AppConfigHistory> historyList;

    // 工厂方法：创建新应用
    public static AppAggregate create(
            AppId id, String appName, String appDesc, ModelId modelId, String createdBy) {
        App newApp = App.create(id, appName, appDesc, modelId);
        AppConfigHistory initialHistory =
                AppConfigHistory.create(
                        newApp.getId(), Version.initial(), newApp.getCurrentConfigSnapshot(), "初始化", createdBy);
        List<AppConfigHistory> history = new ArrayList<>();
        history.add(initialHistory);
        return new AppAggregate(newApp, history);
    }

    // 加载方法 (供仓储使用)
    public static AppAggregate load(App app, List<AppConfigHistory> history) {
        history.sort(
                Comparator.comparing(AppConfigHistory::getVersion).reversed()); // Ensure order by new field
        return new AppAggregate(app, new ArrayList<>(history)); // 返回副本
    }

    // --- 聚合根行为 ---

    // 更新应用基本信息
    public void updateBasicInfo(String newName, String newDesc) {
        app.updateBasicInfo(newName, newDesc);
    }

    // 更新应用配置
    public void updateConfiguration(
            ModelId newModelId,
            boolean useKb,
            KnowledgeBaseId kbId,
            String changeDesc,
            String changedBy) {
        // 1. 更新应用实体配置
        app.updateConfiguration(newModelId, useKb, kbId);

        // 2. 生成新版本号
        Version nextVersion = getCurrentVersion().next();

        // 3. 创建新的历史记录
        AppConfigHistory newHistory =
                AppConfigHistory.create(
                        app.getId(),
                        nextVersion,
                        app.getCurrentConfigSnapshot(),
                        changeDesc != null ? changeDesc : "Configuration updated",
                        changedBy);
        historyList.add(0, newHistory);
    }

    // 回滚到指定历史版本
    public void rollbackToHistory(Version targetVersion, String changeDesc, String changedBy) {
        Optional<AppConfigHistory> targetHistoryOpt =
                historyList.stream().filter(h -> h.getVersion().equals(targetVersion)).findFirst();

        if (targetHistoryOpt.isEmpty()) {
            throw new DomainException("目标版本不存在: " + targetVersion.value());
        }

        AppConfigHistory targetHistory = targetHistoryOpt.get();
        AppConfigSnapshot snapshot = targetHistory.getConfigSnapshot();

        // 1. 更新应用实体配置
        app.updateConfiguration(
                snapshot.modelId(), snapshot.useKnowledgeBase(), snapshot.knowledgeBaseId());

        // 2. 生成新版本号
        Version nextVersion = getCurrentVersion().next();

        // 3. 创建新的历史记录
        String rollbackDesc =
                String.format("回滚版本 %d. %s", targetVersion.value(), changeDesc != null ? changeDesc : "");
        AppConfigHistory newHistory =
                AppConfigHistory.create(
                        app.getId(),
                        nextVersion,
                        app.getCurrentConfigSnapshot(),
                        rollbackDesc.trim(),
                        changedBy);
        historyList.add(0, newHistory); // 添加到列表开头
    }

    // 获取当前版本
    public Version getCurrentVersion() {
        if (historyList.isEmpty()) {
            return Version.initial();
        }
        return historyList.get(0).getVersion();
    }

    // 获取当前配置
    public AppConfigSnapshot getCurrentConfig() {
        if (historyList.isEmpty()) {
            return app.getCurrentConfigSnapshot();
        }
        return historyList.get(0).getConfigSnapshot();
    }

    public List<AppConfigHistory> getConfigHistory() {
        return Collections.unmodifiableList(historyList);
    }
}
